"use strict";
/* var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
}; */

var __decorate2 = function (decorators, target, key, desc) {
  let argsLength = arguments.length;
  //如果长度小于3,装饰target,如果长度大于等于3,装饰方法描述 器
  let decoratorTarget =
    argsLength < 3
      ? target
      : desc == null
      ? (desc = Object.getOwnPropertyDescriptor(target, key))
      : desc;
  for(let i=decorators.length-1;i>=0;i--){
      let decorator = decorators[i];
      /**
       * 注意要倒序调用装饰器
       * 如果长度小于3,说明是类装饰器,直接类组装饰器就可以了
       * 如果长度等于3,主明是类装饰类,并且有key,要把target和key传给装饰器
       * 如果果是大于3的,说明方法装饰器,类 key  desc传给装饰器
       */
      if(decorator){
        decoratorTarget = (
          argsLength<3?decorator(decoratorTarget):argsLength>3?
          decorator(target,key,decoratorTarget):decorator(target,key)
        )||decoratorTarget;
      }
  }    
  return (
    //说明修饰的是方法描述符 重新给目标的key设置方法描述符
    argsLength > 3 &&
      decoratorTarget && 
      Object.defineProperty(target, key, decoratorTarget),
    decoratorTarget
  );
}


Object.defineProperty(exports, "__esModule", { value: true });
require("reflect-metadata");
var InjectionToken = /** @class */ (function () {
    function InjectionToken(injectionIdentifier) {
        this.injectionIdentifier = injectionIdentifier;
    }
    return InjectionToken;
}());
var METADATA_INJECT_KEY = 'METADATA_INJECT_KEY';
//是一个参数装饰器工厂,会返回一个参数装饰器

function Car() {}
function House() {}
function GirlFriend(car, house) {
  this.car = car;
  this.house = house;
}
/**
 * 类装饰器工厂
 * @param {*} paramIndex 这个参数在参数列表中的索引
 * @param {*} decorator 参数装饰器
 */
var __param = function (paramIndex, decorator) {
    return function (target) {//是一个类装饰器target=GirlFriend paramIndex=1
      decorator(target, undefined, paramIndex); //在类装饰器调用了参数装饰器,,是把参数装饰器当成一个普通方法来调用了
    };
};
//也是一个类装饰器工厂
var __metadata =function (key, value) {
    //return Reflect.metadata(key, value);
    return function (target) {//返回一个类装饰器 target是类本身
         Reflect.defineMetadata(key, value, target);
         return target;;
    } 
};
function Inject(token) {//是一个参数装饰器工厂,返回是一个参数装饰器
  return function (target, key, paramsIndex) {
    Reflect.defineMetadata(METADATA_INJECT_KEY,token,target,"index-" + paramsIndex);
    return target;
  };
}
var __decorate = function (decorators, target) {
  for (let i = decorators.length - 1; i >= 0; i--) {
    let decorator = decorators[i];
    target = decorator(target) || target;
  }
  return target;
};
//执行装饰器 从右往前装饰
GirlFriend = __decorate(
  [ __param(1, Inject(new InjectionToken("house"))),//如果用了Inject参数装饰器 
   __metadata("design:paramtypes", [Car, House]),
  ],
  GirlFriend
);
console.log(Reflect.getMetadata("design:paramtypes", GirlFriend));//参数类型列表